package com.zhdl.hardware.robot.borunte.service.impl;

import cn.hutool.core.util.HexUtil;
import com.project.common.util.ByteHelper;
import com.zhdl.common.ytools.callback.CommonCallback;
import com.zhdl.hardware.robot.borunte.repository.BorunteCmdHandleDao;
import com.zhdl.hardware.robot.borunte.service.BorunteCmdSendService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

@Slf4j
@Service
public class BorunteCmdSendServiceImpl implements BorunteCmdSendService {
    @Resource
    public BorunteCmdHandleDao borunteCmdHandleDao;
    @Resource
    public ThreadPoolTaskScheduler taskScheduler1;
    /**
     * M信号管理
     */
    public Map<String, String> robotStatusM = new ConcurrentHashMap<>();

    /**
     * 线程管理
     */
    Map<String, ScheduledFuture<?>> mapSF = new HashMap<>();

    /**
     * 将byte转换为一个长度为8的byte数组，数组每个值代表bit
     */
    public static Byte[] getBitArray(byte b) {
        Byte[] array = new Byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }


    /**
     * 机器人-读取世界坐标
     *
     * @param callback 回调函数
     */
    public void borunteReadLocation(CommonCallback<int[]> callback) {
        borunteCmdHandleDao.borunteReadLocation(bytes -> {
            int[] robotLocationNow = new int[6];
            /* 获取有效数据-机器人的世界坐标 */
            String hexUnitBuff = HexUtil.encodeHexStr(bytes);
            /* 对读取到的数据进行处理-处理读取到的世界坐标 */
            for (int i = 0; i < hexUnitBuff.length(); i++) {
                if (i % 8 == 0) {
                    String substring = hexUnitBuff.substring(i, i + 8);
                    BigInteger bigInteger = new BigInteger(substring, 16);
                    int i1 = bigInteger.intValue();
                    robotLocationNow[i / 8] = i1;
                }
                callback.statusCallback(robotLocationNow);
            }

        });
    }

    public void borunteReadStatusM(int address, int timeout, CommonCallback<String> callback) {
        /* 声明循环次数 */
        final int[] times = new int[]{0};

        String key = address + "_" + System.currentTimeMillis();

        ScheduledFuture<?> scheduledFuture = taskScheduler1.scheduleWithFixedDelay(() ->
                borunteCmdHandleDao.borunteReadSwitch(address, bytes -> {
                    String hexString = ByteHelper.bytesArrayToHexString(bytes);
                    if ("01".equals(hexString)) {
                        ScheduledFuture<?> scheduledFuture0 = mapSF.get(key);
                        scheduledFuture0.cancel(false);
                        mapSF.remove(key);
                        callback.statusCallback("0");
                    } else {
                        /* 超时报警 */
                        times[0]++;
                        if (times[0] > timeout) {
                            ScheduledFuture<?> scheduledFuture0 = mapSF.get(key);
                            scheduledFuture0.cancel(false);
                            mapSF.remove(key);
                            callback.statusCallback("2");
                        }
                        callback.statusCallback("1");
                    }
                }), 100);

        mapSF.put(key, scheduledFuture);
    }

    public void borunteWriteStatusM(int address, boolean open) {
        borunteCmdHandleDao.borunteWriteSwitch(address, open);
    }

    public void borunteSetOriginZ() {
        borunteReadLocation(ints -> borunteCmdHandleDao.borunteSetOriginZ(ints));
    }

    public void borunteSetPickLocation(int[] location) {
//        borunteCmdHandleDao.borunteSetPickZ();
//        borunteCmdHandleDao.borunteSetPickPoint();
    }
}
